package com.katesoft.scale4j.web.webconsole;

import com.katesoft.scale4j.common.lang.RuntimeUtility;
import com.katesoft.scale4j.log.Logger;
import com.katesoft.scale4j.log.LogFactory;
import org.mortbay.jetty.Request;
import org.mortbay.jetty.security.UserRealm;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;

import java.security.Principal;
import java.util.Collection;

/** @author kate2007 */
public class JettySpringSecurityUserRealm implements UserRealm
{
    private Logger logger = LogFactory.getLogger(getClass());
    private AuthenticationManager authenticationManager;

    public JettySpringSecurityUserRealm(AuthenticationManager authenticationManager)
    {
        this.authenticationManager = authenticationManager;
    }

    @Override
    public String getName()
    {
        return "rttp.webconsole.user.realm" + System.getProperty(RuntimeUtility.VAR_SERVICE_ID);
    }

    @Override
    public Principal authenticate(String username,
                                  Object credentials,
                                  Request r)
    {
        Authentication request = new UsernamePasswordAuthenticationToken(username, credentials.toString());
        try {
            Authentication response = authenticationManager.authenticate(request);
            String user = response.getPrincipal().toString();
            String password = response.getCredentials().toString();
            Collection<GrantedAuthority> authorities = response.getAuthorities();
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(user, password, authorities);
            logger.debug("authenticated user=%s with credentials=%s", username, credentials);
            return token;
        }
        catch (AuthenticationException failed) {
            logger.debug("Authentication request for user[%s] failed: [%s] ", username, failed.getMessage());
        }
        return null;
    }

    @Override
    public boolean reauthenticate(Principal user)
    {
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) user;
        return token.isAuthenticated();
    }

    @Override
    public boolean isUserInRole(Principal user,
                                String role)
    {
        boolean userInRole = false;
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) user;
        Collection<GrantedAuthority> authorities = token.getAuthorities();
        for (GrantedAuthority authority : authorities) {
            if (authority.getAuthority().equals(role)) { userInRole = true; }
        }
        logger.debug("user=%s is in role=%s :=> %s", user.toString(), role, userInRole);
        return userInRole;
    }

    @Override
    public void disassociate(Principal user)
    {
    }

    @Override
    public Principal pushRole(Principal user,
                              String role)
    {
        return user;
    }

    @Override
    public Principal popRole(Principal user)
    {
        return user;
    }

    @Override
    public void logout(Principal user)
    {
        logger.debug("onLogout(%s)", user);
    }

    @Override
    public Principal getPrincipal(String username)
    {
        return null;
    }
}
